<?php

namespace api\modules\v1\forms\rbac;

use Yii;
use yii\base\Model;
use common\models\member\Member;
use common\models\rbac\Action;
use common\models\rbac\Menu;
use common\models\rbac\Module;
use common\models\rbac\RolePermission;

/**
 * 菜单
 *
 * Class MenuForm
 * @package api\modules\v1\forms\rbac
 */
class MenuForm extends Model
{
    /**
     * 菜单ID
     *
     * @var
     */
    public $id;

    /**
     * 模块ID
     *
     * @var
     */
    public $module_id;

    /**
     * 父菜单ID
     *
     * @var
     */
    public $parent_menu_id;

    /**
     * 菜单名
     *
     * @var
     */
    public $name;

    /**
     * 菜单名
     *
     * @var
     */
    public $flag;

    /**
     * 菜单url
     *
     * @var
     */
    public $url;

    /**
     * 菜单ico
     *
     * @var
     */
    public $class_style;

    /**
     * 菜单状态
     *
     * @var
     */
    public $status;

    /**
     * 菜单排序
     *
     * @var
     */
    public $sort;

    /**
     * 用户ID
     *
     * @var
     */
    public $member_id;


    /**
     * 菜单信息
     *
     * @var array
     */
    protected $menu;


    public function rules()
    {
        return [
            // 参数验证
            [['member_id', 'name', 'module_id', 'url', 'class_style', 'status'], 'required', 'message' => '{attribute}不能为空', 'on' => ['create']],
            [['member_id', 'id', 'name', 'module_id', 'url', 'class_style', 'status'], 'required', 'message' => '{attribute}不能为空', 'on' => ['edit']],
            [['member_id', 'id'], 'required', 'message' => '{attribute}不能为空', 'on' => ['delete']],

            [['member_id'], 'checkMemberId', 'skipOnEmpty' => false, 'on' => ['create', 'edit', 'delete', 'edit-status']],
            [['id'], 'checkMenu', 'skipOnEmpty' => false, 'on' => ['edit', 'delete', 'edit-status']],
            [['name'], 'checkName', 'skipOnEmpty' => false, 'on' => ['create', 'edit']],
            [['module_id'], 'checkModuleId', 'skipOnEmpty' => true, 'on' => ['create', 'edit']],
            [['parent_menu_id'], 'checkParentMenuId', 'skipOnEmpty' => true, 'on' => ['create', 'edit']],
            [['url'], 'checkUrl', 'skipOnEmpty' => false, 'on' => ['create', 'edit']],
            [['class_style'], 'checkClassStyle', 'skipOnEmpty' => false, 'on' => ['create', 'edit']],
            [['sort'], 'checkSort', 'skipOnEmpty' => true, 'on' => ['create', 'edit']],
            [['status'], 'checkStatus', 'skipOnEmpty' => false, 'on' => ['create', 'edit', 'edit-status']],
        ];
    }

    public function scenarios()
    {
        $scenarios = parent::scenarios();

        // 新增
        $scenarios['create'] = ['member_id', 'name', 'module_id', 'parent_menu_id', 'url', 'class_style', 'sort', 'status'];

        // 编辑
        $scenarios['edit'] = ['member_id', 'id', 'name', 'module_id', 'parent_menu_id', 'url', 'class_style', 'sort', 'status'];

        // 删除
        $scenarios['delete'] = ['member_id', 'id'];

        // 编辑状态
        $scenarios['edit-status'] = ['member_id', 'id', 'status'];

        return $scenarios;
    }

    /**
     * @return array
     */
    public function attributeLabels()
    {
        return [
            'member_id' => '用户ID',
            'id' => '菜单ID',
            'name' => '菜单名称',
            'module_id' => '模块',
            'parent_menu_id' => '父菜单',
            'url' => '菜单链接',
            'class_style' => '菜单icon',
            'sort' => '菜单排序',
            'status' => '菜单状态',
        ];
    }

    /**
     * 检验用户UID
     *
     * @param $attribute
     * @return bool
     */
    public function checkMemberId($attribute)
    {
        if ($this->hasErrors()) {
            return true;
        }

        $member = Yii::$app->services->member->getInfo(['id' => $this->member_id]);
        if ($member['is_super'] != Member::IS_SUPER_YES) {
            $this->addError($attribute, '非超管，无权限操作');
            return true;
        }
    }

    /**
     * 检验菜单信息
     *
     * @param $attribute
     * @return bool
     */
    public function checkMenu($attribute)
    {
        if ($this->hasErrors()) {
            return true;
        }

        $menu = $this->getMenu();
        if (!$menu) {
            $this->addError($attribute, '参数错误[id_error]');
            return true;
        }

        if ($menu->status == Menu::STATUS_DELETE) {
            $this->addError($attribute, '菜单已删除，无法操作');
            return true;
        }

        if (($this->getScenario() == 'edit' && $this->status == Menu::STATUS_INVALID)
            || $this->getScenario() == 'delete') {
            $rolePermission = Yii::$app->services->rolePermission->findInfo([
                'permission_id' => $this->id,
                'permission_type' => RolePermission::PERMISSION_TYPE_MENU,
            ]);
            if ($rolePermission) {
                $this->addError($attribute, "该菜单被角色绑定，无法操作");
                return true;
            }

            $menu = Yii::$app->services->menu->findInfo([
                'parent_menu_id' => $this->id,
                'status' => Menu::STATUS_ENABLE,
            ]);
            if ($menu) {
                $this->addError($attribute, "该菜单存在子级，无法操作");
                return true;
            }

            $action = Yii::$app->services->action->findInfo([
                'menu_id' => $this->id,
                'status' => Action::STATUS_ENABLE,
            ]);
            if ($action) {
                $this->addError($attribute, "该菜单存在动作行为，无法操作");
                return true;
            }
        }
    }

    /**
     * 校验菜单名称
     *
     * @param $attribute
     */
    public function checkName($attribute)
    {
        if ($this->hasErrors()) {
            return true;
        }

        $len = mb_strlen($this->name);
        if ($len > 10) {
            $this->addError($attribute, '菜单名称过长，最多10个字');
            return true;
        }

        // 是否检验
        $isCheck = true;
        if ($this->getScenario() == 'edit') {
            $menu = $this->getMenu();
            // 菜单参数未改变【跳过】
            if ($menu->name == $this->name && $menu->parent_menu_id == $this->parent_menu_id) {
                $isCheck = false;
            }
        }

        if ($isCheck) {
            $menuInfo = Yii::$app->services->menu->findInfo([
                'name' => $this->name,
                'parent_menu_id' => $this->parent_menu_id,
                'status' => [Menu::STATUS_INVALID, Menu::STATUS_ENABLE],
            ]);
            if ($menuInfo) {
                $this->addError($attribute, "菜单【{$this->name}】已存在");
                return true;
            }
        }
    }

    /**
     * 校验模块ID
     *
     * @param $attribute
     */
    public function checkModuleId($attribute)
    {
        if ($this->hasErrors()) {
            return true;
        }

        $module = Yii::$app->services->module->findById($this->module_id);
        if (!$module) {
            $this->addError($attribute, '模块不存在');
            return true;
        }

        if ($module->status != Module::STATUS_ENABLE) {
            $this->addError($attribute, '模块未启用，无法操作');
            return true;
        }
    }

    /**
     * 校验父菜单ID
     *
     * @param $attribute
     */
    public function checkParentMenuId($attribute)
    {
        if ($this->hasErrors()) {
            return true;
        }

        if ($this->parent_menu_id == 0) {
            return true;
        }

        $parentMenu = Yii::$app->services->menu->findById($this->parent_menu_id);
        if (!$parentMenu) {
            $this->addError($attribute, '参数错误[parent_menu_id_error]');
            return true;
        }

        if ($parentMenu->status == Menu::STATUS_DELETE) {
            $this->addError($attribute, '菜单已删除，无法操作');
            return true;
        }

        if ($parentMenu->module_id != $this->module_id) {
            $this->addError($attribute, '非当前模块菜单');
            return true;
        }
    }

    /**
     * 校验菜单url
     *
     * @param $attribute
     */
    public function checkUrl($attribute)
    {
        if ($this->hasErrors()) {
            return true;
        }

        $len = strlen($this->url);
        if ($len > 80) {
            $this->addError($attribute, '菜单链接过长，最多80个字节');
            return true;
        }
    }

    /**
     * 校验菜单icon
     *
     * @param $attribute
     */
    public function checkClassStyle($attribute)
    {
        if ($this->hasErrors()) {
            return true;
        }

        $len = strlen($this->class_style);
        if ($len > 50) {
            $this->addError($attribute, '菜单icon过长，最多50个字节');
            return true;
        }
    }

    /**
     * 校验菜单排序
     *
     * @param $attribute
     */
    public function checkSort($attribute)
    {
        if ($this->hasErrors()) {
            return true;
        }

        if ($this->sort < 0) {
            $this->addError($attribute, '排序值不能小于0');
            return true;
        }
    }

    /**
     * 校验菜单状态
     *
     * @param $attribute
     */
    public function checkStatus($attribute)
    {
        if ($this->hasErrors()) {
            return true;
        }

        if (!in_array($this->status, [Menu::STATUS_INVALID, Menu::STATUS_ENABLE])) {
            $this->addError($attribute, "参数错误[status_error]");
            return true;
        }
    }

    /**
     * 获取菜单信息
     *
     * @return array|Menu|null
     */
    public function getMenu()
    {
        if (empty($this->menu)) {
            $this->menu = Yii::$app->services->menu->findById($this->id);
        }

        return $this->menu;
    }
}
